%    Copyright (C) 2002 Aladdin Enterprises.  All rights reserved.
% 
% This software is provided AS-IS with no warranty, either express or
% implied.
% 
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
% 
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.

% $Id: gs_devcs.ps,v 1.7 2005/09/12 11:34:50 leonardo Exp $
% Device-specific color space method dictionaries.

%
% This file implements the method dictionaries for the Device-specific
% color spaces. See gs_cspace.ps for information.
%
% Note that, because these color spaces are parameter-less, no color
% space validation is required: if we can get to the color space methods,
% we know the color space is legitimate.
%
% The colorspace substitution routines for these color spaces
% (cs_substitute) will fail in a Level 1 system, but this is not a
% problem as .getuseciecolor will always return false for such systems.
%
.currentglobal true .setglobal
.cspace_util begin

%
%   <r>  <g>  <b>   rgb_2_gray   <gray>
%
% Convert RGB colors to gray. This includes a special check for
% r == g == b, and avoids roundoff error if this is the case.
%
/rgb_2_gray
  {
    3 copy 1 index eq 3 1 roll eq and
      { pop pop }
      { .11 mul exch .59 mul add exch .3 mul add }
    ifelse
  }
bind def

systemdict /..page_default_spaces 3 dict put

% <color_space_name> ..includecolorspace -
/..includecolorspace
{ % Only includes ones explicitly defined by the document.
  systemdict /..page_default_spaces get 1 index known {
    pop
  } {
    mark exch
    { dup /ColorSpace resourcestatus {
        pop 0 eq {
          systemdict /..page_default_spaces get 1 index //true put
          gsave
          { dup /ColorSpace findresource //_setcolorspace_nosub exec .includecolorspace
          } stopped pop
          grestore
        } if
      } if
    } stopped pop
    cleartomark
  } ifelse
} bind def

% <color_space> <color_space_name> cs_substitute_generic <color_space1> <color_space2>
/cs_substitute_generic
{ .getuseciecolor
    { NOSUBSTDEVICECOLORS 
        { //..includecolorspace exec dup }
        { /ColorSpace findresource }
      ifelse
    }
    { pop dup }
  ifelse
}
bind def

% <color_space> <color_space_name> cs_substitute_DeviceRGB_for_PDFX <color_space1> <color_space2>
/cs_substitute_DeviceRGB_for_PDFX
{ systemdict /PDFX .knownget not { false } if {
    dup /ColorSpace resourcestatus {
      pop pop
    } {
      (Error: Need a /DefaultRGB /ColorSpace resource for generating a PDF/X document.) =
      /cs_substitute_DeviceRGB_for_PDFX /undefined signalerror
    } ifelse
    /ColorSpace findresource
  } {
    //cs_substitute_generic exec
  } ifelse   
} bind def

colorspacedict

dup
/DeviceGray
  mark
    /cs_potential_indexed_base true
    /cs_potential_pattern_base true
    /cs_potential_alternate true
    /cs_potential_icc_alternate true
    /cs_get_ncomps //ncomps_1
    /cs_get_range  //get_range_1
    /cs_get_default_color { pop 0 } bind
    /cs_get_currentgray //pop_1
    /cs_get_currentrgb { pop dup dup } bind
    /cs_get_currentcmyk { pop 1 exch sub 0 0 0 4 -1 roll } bind
    /cs_validate {}

    /cs_substitute
      { /DefaultGray //cs_substitute_generic exec
      }
    bind

    /cs_prepare {}
    /cs_install { pop 0 .setdevcspace } bind
    /cs_prepare_color //validate_1
    /cs_complete_setcolor //pop_1
  .dicttomark
put


/DeviceRGB
  mark
    /cs_potential_indexed_base true
    /cs_potential_pattern_base true
    /cs_potential_alternate true
    /cs_potential_icc_alternate true
    /cs_get_ncomps //ncomps_3
    /cs_get_range  //get_range_3
    /cs_get_default_color { pop 0 0 0 } bind
    /cs_get_currentgray { pop //rgb_2_gray exec } bind
    /cs_get_currentrgb //pop_1

    % to convert to cmyk use blackgeneration and undercolorremoval
    /cs_get_currentcmyk
      {
        pop

        % convert to subtractive (CMY) color space
        3
          { 1 exch sub 3 1 roll }
        repeat

        % find the minimum (initial k component)
        3 copy
        2
          {
            2 copy gt
              { exch }
            if
            pop
          }
        repeat

        % apply undercolorremoval
        dup 5 1 roll currentundercolorremoval exec 4 1 roll
        3
          { 3 index sub //bound_0_1 exec 3 1 roll }
        repeat

        % apply blackgeneration
        5 3 roll pop currentblackgeneration exec //bound_0_1 exec
      }
    bind

    /cs_validate {}

    /cs_substitute
      { /DefaultRGB //cs_substitute_DeviceRGB_for_PDFX exec
      }
    bind

    /cs_prepare {}
    /cs_install { pop 1 .setdevcspace } bind
    /cs_prepare_color //validate_3
    /cs_complete_setcolor //pop_1
  .dicttomark
put

end     % .cspace_util
.setglobal


% Only create the DeviceCMYK color space if setcolorscreen is present
/setcolorscreen where
  { pop }
  { currentfile closefile }
ifelse


.currentglobal true .setglobal
.cspace_util begin

colorspacedict
/DeviceCMYK
  mark
    /cs_potential_indexed_base true
    /cs_potential_pattern_base true
    /cs_potential_alternate true
    /cs_potential_icc_alternate true
    /cs_get_ncomps //ncomps_4
    /cs_get_range  //get_range_4
    /cs_get_default_color { pop 0 0 0 1 } bind

    /cs_get_currentgray
      { pop 4 1 roll //rgb_2_gray exec add 1 exch sub //bound_0_1 exec }
    bind

    /cs_get_currentrgb 
      {
        pop
        4 1 roll 3
          { 3 index add  1 exch sub //bound_0_1 exec 3 1 roll }
        repeat
        4 -1 roll pop
      }
    bind

    /cs_get_currentcmyk //pop_1

    /cs_validate {}

    /cs_substitute
      { /DefaultCMYK //cs_substitute_generic exec
      }
    bind

    /cs_prepare {}
    /cs_install { pop 2 .setdevcspace } bind
    /cs_prepare_color //validate_4
    /cs_complete_setcolor //pop_1
  .dicttomark
put

currentdict /..includecolorspace .undef
currentdict /cs_substitute_generic .undef

end     % .cspace_util
.setglobal

